package net.csdn.business.notify.api.action;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.notify.api.service.INotifyTemplateSetingService;
import net.csdn.business.notify.common.config.TargetTypeConfig;
import net.csdn.business.notify.common.constant.CommonConstants;
import net.csdn.business.notify.common.enums.NotifyChannel;
import net.csdn.business.notify.common.enums.ProcessStatusEnum;
import net.csdn.business.notify.common.model.query.NotifyTemplateSetingQuery;
import net.csdn.business.notify.common.model.vo.*;
import net.csdn.business.notify.common.pipeline.BusinessProcess;
import net.csdn.business.notify.common.pipeline.ProcessContext;
import net.csdn.business.notify.common.pipeline.domain.SendTaskModel;
import net.csdn.business.notify.common.pipeline.domain.TaskInfo;
import net.csdn.business.notify.common.pipeline.model.ContentModel;
import net.csdn.business.notify.common.pipeline.param.MessageParam;
import net.csdn.business.notify.common.pipeline.param.SendRemindParam;
import net.csdn.business.notify.common.utils.ContentHolderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.*;


/**
 * @ClassName DirectAssembleAction
 * @Description TODO
 * @Author zhangyl
 * @Date 2023/12/20 14:06
 */
@Slf4j
@Service
public class DirectAssembleAction implements BusinessProcess<SendTaskModel> {

    @Autowired
    private INotifyTemplateSetingService templateService;

    @Override
    public void process(ProcessContext<SendTaskModel> context) {
        NotifyResponseVO response=context.getResponse();
        Map<String,String> failMap=response.getFail();
        SendTaskModel sendTaskModel = context.getProcessModel();
        List<MessageParam> messageParamList = sendTaskModel.getMessageParamList();
        List<TaskInfo> taskInfos = new ArrayList<>();
        for (MessageParam messageParam : messageParamList) {
            SendRemindParam sendRemindParam =(SendRemindParam)messageParam;
            Long busId = Long.parseLong(sendRemindParam.getBusId());
            Integer notifyType=sendRemindParam.getNotifyType();
            String busCode=sendRemindParam.getBusCode();
            String targetType=sendRemindParam.getTargetType();
            String act=sendRemindParam.getAct();
            String batchNum= sendRemindParam.getBatchNum();
            NotifyTemplateSetingQuery query=new NotifyTemplateSetingQuery();
            query.setBusinessId(busId);
            query.setState(1);//查询打开的模板
            List<NotifyTemplateSetingVO> messageTemplates =templateService.selectNotifyTemplateSetingList(query);
            if(messageTemplates==null||messageTemplates.size()==0){
                failMap.put(batchNum,ProcessStatusEnum.TEMPLATE_NOT_FOUND.getMsg());
                continue;
            }
            for (NotifyTemplateSetingVO messageTemplate:messageTemplates){
                Integer notifyChannel=messageTemplate.getNotifyChannel();
                ContentModel contentModel=null;
                try{
                     contentModel=getContentModelValue(messageTemplate, sendRemindParam);
                }catch (Exception e){
                    e.printStackTrace();
                    failMap.put(batchNum,ProcessStatusEnum.TEMPLATE_CONNTENT_ERROR.getMsg());
                    continue;
                }
                TaskInfo taskInfo = TaskInfo.builder()
                        .businessCode(busCode)
                        .notifyType(notifyType)
                        .receiver(sendRemindParam.getReceiver())
                        .notifyChannel(notifyChannel)
                        .batchNum(batchNum)
                        .nameSpace(sendRemindParam.getNameSpace())
                        .act(targetType)
                        .url(sendRemindParam.getUrl())
                        .targetId(sendRemindParam.getTargetId())
                        .targetType(act)
                        .senderId(sendRemindParam.getSender())
                        .sendDate(new Date())
                        .contentModel(JSON.toJSONString(contentModel)).startTime(context.getStartTime()).build();
                taskInfos.add(taskInfo);
            }
        }
        if(taskInfos.size()==0){
            response.setStatus(ProcessStatusEnum.FAIL);
            context.setNeedBreak(true);
            return;
        }
        sendTaskModel.setTaskInfo(taskInfos);
    }



    /**
     * 获取 contentModel，替换模板msgContent中占位符信息
     */
    private  ContentModel getContentModelValue(NotifyTemplateSetingVO messageTemplate, SendRemindParam messageParam) {
        // 得到真正的ContentModel 类型
        Integer sendChannel = messageTemplate.getNotifyChannel();
        Class<? extends ContentModel> contentModelClass = NotifyChannel.getChanelModelClassByCode(sendChannel);
        // 得到模板的 msgContent 和 入参
        Map<String, String> variables = messageParam.getVariables();
       /* JSONObject nameSpace=messageParam.getNameSpace();
        String targetType=messageParam.getTargetType();
        String act=messageParam.getAct();*/
        JSONObject jsonObject = messageTemplate.getTemplate();
        // 通过反射 组装出 contentModel
        Field[] fields = ReflectUtil.getFields(contentModelClass);
        ContentModel contentModel = ReflectUtil.newInstance(contentModelClass);
        for (Field field : fields) {
            String fieldName=field.getName();
            String originValue = jsonObject.getString(fieldName);
            if (StrUtil.isNotBlank(originValue)) {
                String resultValue = ContentHolderUtil.replacePlaceHolder(originValue, variables);
                if(NotifyChannel.EMAIL.getCode().equals(sendChannel)&&CommonConstants.EMAIL_TILTE.equals(fieldName)){
                    StringBuilder titleStr=new StringBuilder("AtomGit");
                    titleStr.append(" | ");
                    titleStr.append(resultValue);
                    resultValue=titleStr.toString();
                }
                Object resultObj = JSONUtil.isJsonObj(resultValue) ? JSONUtil.toBean(resultValue, field.getType()) : resultValue;
                ReflectUtil.setFieldValue(contentModel, field, resultObj);
            }
        }
        return contentModel;
    }

}
